
package org.apache.solr.core;

import java.util.List;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList;
import org.apache.solr.search.SolrIndexSearcher;

public class QuerySenderListener extends AbstractSolrEventListener {

    public QuerySenderListener(SolrCore core) {
        super(core);
    }

    @Override
    public void newSearcher(SolrIndexSearcher newSearcher, SolrIndexSearcher currentSearcher) {

        final SolrIndexSearcher searcher = newSearcher;
        log.info("QuerySenderListener sending requests to " + newSearcher);
        List<NamedList> allLists = (List<NamedList>) args.get("queries");
        if (allLists == null) {
            return;
        }
        for (NamedList nlst : allLists) {
            SolrQueryRequest req = null;

            try {
                // bind the request to a particular searcher (the newSearcher)
                NamedList params = addEventParms(currentSearcher, nlst);
                // for this, we default to distrib = false
                if (params.get("distrib") == null) {
                    params.add("distrib", false);
                }
                req = new LocalSolrQueryRequest(core, params) {
                    @Override
                    public SolrIndexSearcher getSearcher() {
                        return searcher;
                    }

                    @Override
                    public void close() {
                    }
                };

                SolrQueryResponse rsp = new SolrQueryResponse();
                SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp));
                core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp);

                // Retrieve the Document instances (not just the ids) to warm
                // the OS disk cache, and any Solr document cache.  Only the top
                // level values in the NamedList are checked for DocLists.
                NamedList values = rsp.getValues();
                for (int i = 0; i < values.size(); i++) {
                    Object o = values.getVal(i);
                    if (o instanceof DocList) {
                        DocList docs = (DocList) o;
                        for (DocIterator iter = docs.iterator(); iter.hasNext();) {
                            newSearcher.doc(iter.nextDoc());
                        }
                    }
                }

            }
            catch (Exception e) {
                // do nothing... we want to continue with the other requests.
                // the failure should have already been logged.
            }
            finally {
                if (req != null) {
                    req.close();
                }
                SolrRequestInfo.clearRequestInfo();
            }
        }
        log.info("QuerySenderListener done.");
    }
}
